import os
import win32com.client as win32
from pathlib import Path

class XlsXlsxSwitcher:
    """
    Excel 文件格式转换工具 (XLS ↔ XLSX)
    使用 Microsoft Excel COM 接口实现高质量格式转换
    
    功能:
    - xls_to_xlsx: 将 .xls 转换为 .xlsx
    - xlsx_to_xls: 将 .xlsx 转换为 .xls
    - 支持自动生成输出路径或指定输出路径
    - 支持覆盖已存在文件
    """
    
    # Excel 文件格式常量
    FILE_FORMATS = {
        'xls': 56,   # Excel 97-2003 工作簿 (.xls)
        'xlsx': 51,  # Excel 工作簿 (.xlsx)
    }
    
    def __init__(self, visible=False, display_alerts=False):
        """
        初始化转换器
        
        参数:
        - visible: bool, 是否显示 Excel 界面 (默认 False)
        - display_alerts: bool, 是否显示 Excel 警告 (默认 False)
        """
        self.excel = None
        self.visible = visible
        self.display_alerts = display_alerts
    
    def __enter__(self):
        """支持 with 语句"""
        self._start_excel()
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """退出时关闭 Excel"""
        self._quit_excel()
    
    def _start_excel(self):
        """启动 Excel 应用"""
        if self.excel is None:
            self.excel = win32.gencache.EnsureDispatch('Excel.Application')
            self.excel.Visible = self.visible
            self.excel.DisplayAlerts = self.display_alerts
    
    def _quit_excel(self):
        """关闭 Excel 应用"""
        if self.excel is not None:
            self.excel.Quit()
            self.excel = None
    
    def _get_output_path(self, input_path, target_ext):
        """生成默认输出路径"""
        input_path = Path(input_path)
        return input_path.with_suffix(f'.{target_ext}')
    
    def _convert_format(self, input_path, output_path, target_format):
        """
        执行实际转换操作
        
        参数:
        - input_path: 输入文件路径
        - output_path: 输出文件路径
        - target_format: 目标格式代码
        """
        try:
            self._start_excel()
            
            # 检查输入文件是否存在
            if not os.path.exists(input_path):
                raise FileNotFoundError(f"输入文件不存在: {input_path}")
            
            # 解析输出路径
            output_path = str(Path(output_path).absolute())
            
            # 打开工作簿并转换
            workbook = self.excel.Workbooks.Open(str(Path(input_path).absolute()))
            workbook.SaveAs(output_path, FileFormat=target_format)
            workbook.Close(False)
            
            return True
        
        except Exception as e:
            print(f"转换失败: {str(e)}")
            return False
    
    def xls_to_xlsx(self, input_path, output_path=None):
        """
        将 XLS 文件转换为 XLSX 格式
        
        参数:
        - input_path: 输入的 .xls 文件路径
        - output_path: 输出的 .xlsx 文件路径 (可选)
        
        返回: bool, 是否转换成功
        """
        if output_path is None:
            output_path = self._get_output_path(input_path, 'xlsx')
        
        return self._convert_format(
            input_path=input_path,
            output_path=output_path,
            target_format=self.FILE_FORMATS['xlsx']
        )
    
    def xlsx_to_xls(self, input_path, output_path=None):
        """
        将 XLSX 文件转换为 XLS 格式
        
        参数:
        - input_path: 输入的 .xlsx 文件路径
        - output_path: 输出的 .xls 文件路径 (可选)
        
        返回: bool, 是否转换成功
        """
        if output_path is None:
            output_path = self._get_output_path(input_path, 'xls')
        
        return self._convert_format(
            input_path=input_path,
            output_path=output_path,
            target_format=self.FILE_FORMATS['xls']
        )


# 使用示例
if __name__ == "__main__":
    # 示例1: 使用 with 语句自动管理资源
    with XlsXlsxSwitcher() as converter:
        # XLS 转 XLSX
        converter.xls_to_xlsx("example.xls", "example_converted.xlsx")
        
        # XLSX 转 XLS
        converter.xlsx_to_xls("example.xlsx", "example_converted.xls")
    
    # # 示例2: 手动管理
    converter = XlsXlsxSwitcher()
    try:
        # 自动生成输出文件名
        converter.xls_to_xlsx("example.xls")  # 输出 test.xlsx
        converter.xlsx_to_xls("example.xls") # 输出 test.xls
    finally:
        converter._quit_excel()